package spring.DI;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
import spring.DI.methodDI.BeansConfig;
import spring.factoryBean.ColorEnum;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * Spring 的 Java配置类：
 *      根据 ASPECTJ表达式 过滤 spring.DI.methodDI包下的所有类
 *
 * @author ME
 * @date   2019/9/26
 */
@Configuration
@ComponentScan(value = "spring.DI", excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "spring.DI.methodDI.*"),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BeansConfig.class),
    }
)
@ImportResource({"classpath:spring/DI/spring-setter.xml"})
@EnableSpringConfigured
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
public class DIConfig {
    @Autowired
    private Map<String, IndexDao> indexDaoMap;
    @PostConstruct
    public void postConstruct() {
        // 同样以 Map接收，比 IndexService 缺少一个 indexDaoImpl1 实例
        System.out.println("DIConfig PostConstruct：" + indexDaoMap);
    }
    // -----------------------------------------------------

    /**
     * 把枚举对象声明为 Spring Bean，并注入其他 Bean
     */
    @Bean
    public ColorEnum red(ApplicationContext context) {
        ColorEnum.RED.setContext(context);
        return ColorEnum.RED;
    }

    @Bean
    public IndexService2 indexServiceImpl2() {
        IndexService2 service = new IndexService2();
        service.setDao(indexDaoImpl1());
        return service;
    }

    /**
     * TODO `@Bean` 标注的普通 bean方法不能带 static，否则会调用 2次！！为什么 BeanPostProcessors 不会？？？？？
     *  猜测是 Spring 对 BeanPostProcessors 特殊处理了
     */
    // @Bean({"indexDao1", "indexDaoImpl1"})
    @Bean({"indexDaoImpl1", "indexDao1"})
    // public static IndexDao indexDaoImpl1() {
    public IndexDao indexDaoImpl1() {
        return new IndexDaoImpl1();
    }

    @Bean
    public  TestStaticPriority testStaticPriority() {
        return new TestStaticPriority();
    }

}
